# -*- coding: utf-8 -*-
'''
Created on 2013-4-11

@author: cl.lam
'''

import traceback
from webhelpers import paginate
from flask import current_app as app
from flask import g, render_template, flash, session, redirect, url_for, request
from flask.blueprints import Blueprint
from sqlalchemy.sql.expression import and_


from sys2do.views import BasicView
from sys2do.util.decorator import templated, loginRequired, activetab, \
    mypaginate, allPermission
from sys2do.model import db, qry, Group, Shop, ShopProfile, InventoryLocation, \
     FinAccount, SysLog, SysFile

from sys2do.util.common import _g, _gld, multiupload, _gl
from wtforms.fields.simple import HiddenField
from sys2do.constant import TAB_BASIC, ACTIVE, SHOP_TYPE_MAIN, SHOP_TYPE_BRANCH, \
    SHOP_SALE_TYPE_JOIN, SHOP_SALE_TYPE_SELF, MSG_SAVE_SUCC, MESSAGE_INFO, \
    MSG_SERVER_ERROR, MESSAGE_ERROR, MSG_NO_ID_SUPPLIED, MSG_RECORD_NOT_EXIST, \
    MSG_DELETE_SUCC, LOG_TYPE_DEL, LOG_TYPE_CREATE, LOG_TYPE_UPDATE, \
    MSG_UPDATE_SUCC
from sys2do.util.logic_helper import makeUpdateLog


__all__ = ['bpShop']

bpShop = Blueprint( 'bpShop', __name__ )

class ShopView( BasicView ):

    template_folder = "mas.shop"

    @templated( "index.html" )
    @activetab( TAB_BASIC )
    @mypaginate( 'result' )
#     @allPermission( ['SHOP_VIEW_ALL', ] )
    @loginRequired
    def index( self ):
        if request.method == 'POST':
            form = SrhForm( request.form )
            session[url_for( '.view' )] = form
        else:
            form = session.get( url_for( '.view' ), SrhForm( request.form ) )
        form.url = url_for( '.view' )

        cds = [Shop.active == ACTIVE, ShopProfile.active == ACTIVE, Shop.id == ShopProfile.shopID, ]
        if form.no.data : cds.append( Shop.no.like( '%%%s%%' % form.no.data ) )
        if form.name.data : cds.append( Shop.name.like( '%%%s%%' % form.name.data ) )
        if _g( 'saleType' ) : cds.append( ShopProfile.saleType == _g( 'saleType' ) )
        if _g( 'shopType' ) : cds.append( ShopProfile.shopType == _g( 'shopType' ) )
        if form.createTimeFrom.data : cds.append( Shop.createTime > form.createTimeFrom.data )
        if form.createTimeTo.data : cds.append( Shop.createTime < form.createTimeTo.data )

        result = qry( Shop, ShopProfile ).filter( and_( *cds ) ).order_by( Shop.name )
        return {'form' : form, 'result' : result, }


    @templated( 'view.html' )
    def view( self ):
        sid = _g( 'id' )
        if not sid :
            flash( MSG_NO_ID_SUPPLIED, MESSAGE_ERROR )
            return redirect( url_for( 'bpRoot.view' ) )
        obj = Shop.get( sid )
        if not obj:
            flash( MSG_RECORD_NOT_EXIST, MESSAGE_ERROR )
            return redirect( url_for( 'bpRoot.view' ) )

        spobj = obj.getProfile()

        return {'obj' : obj, 'spobj' : spobj}



    @templated( "add.html" )
    @allPermission( ['SHOP_CREATE', ] )
    @loginRequired
    def add( self ):
        form = AddForm( request.form )
        if request.method == 'GET': return {'form' : form}
        try:
            # ctrete shop,profile,group,inventory
            params = _gld( 'name', 'shortName', 'provinceID', 'cityID', 'address', 'fund', 'legalPerson' , 'remark' )
            params['attachment'] = multiupload()
            obj = Shop.create( params )
            gp = Group( name = "TMP", remark = "User group for shop:[%s]" % params['shortName'] )
            ivt = InventoryLocation( name = obj.shortName, parentID = None, type = 0, fullPath = obj.shortName )

            spparams = _gld( 'shopType', 'saleType' )
            for n in ['canSale', 'canPurchase', 'canGetWarehouse', 'canUpdateProduct', 'canUpdateOfficer']:
                vs = _gl( n )
                spparams[n] = 0 if vs else 1
            sp = ShopProfile( shop = obj, inventory = ivt, **spparams )

            accParam = _gld( 'accname', 'accbankID', 'acccode', 'acccurrencyID', 'acccurrencyID', 'accpaytypeID',
                            'accowner', 'accamount' )
            accTmp = {'shopProfile' : sp}
            for k in accParam:  accTmp[k.replace( 'acc', '' )] = accParam[k]
            fa = FinAccount.create( accTmp )

            db.add_all( [obj, gp, ivt, sp, fa] )
            db.flush()
            gp.referID = sp.id
            gp.name = 'GP4%s' % obj.no
            ivt.referID = sp.id
            ivt.fullPathIDs = ivt.id
            sp.groupIDs = [gp.id]
            db.add( SysLog( refClz = obj.__class__.__name__, type = LOG_TYPE_CREATE, refID = obj.id, ) )
            db.commit()
            flash( MSG_SAVE_SUCC, MESSAGE_INFO )
        except Exception, e:
            traceback.print_exc()
            db.rollback()
            flash( MSG_SERVER_ERROR, MESSAGE_ERROR )
#             return {'form' : form}
            return redirect( url_for( '.view' ) )
        else:
            return redirect( url_for( '.view', action = 'view', id = obj.id ) )


    @templated( "update.html" )
    @allPermission( ['SHOP_EDIT', ] )
    @loginRequired
    def update( self ):
        sid = _g( 'id' )
        if not sid :
            flash( MSG_NO_ID_SUPPLIED, MESSAGE_ERROR )
            return redirect( url_for( '.view' ) )

        obj = Shop.get( sid )
        if not obj:
            flash( MSG_RECORD_NOT_EXIST, MESSAGE_ERROR )
            return redirect( url_for( '.view' ) )

        spobj = obj.getProfile()
        if request.method != 'POST': return {'obj' : obj, 'spobj' : spobj}

        try:
            oldCopy = obj.serialize()
            extLog = []
            for attr in ['name', 'shortName', 'provinceID', 'cityID', 'address', 'fund', 'legalPerson' , 'remark']:
                setattr( obj, attr, _g( attr ) )

            spobj = obj.getProfile()
            spparams = _gld( 'shopType', 'saleType' )
            for n, label in [( 'canSale', u'销售产品模块' ), ( 'canPurchase', u'采购产品模块' ),
                             ( 'canGetWarehouse', u'仓存模块' ), ( 'canUpdateProduct', u'更新商品模块' ),
                             ( 'canUpdateOfficer', u'更新人员模块' )]:
                vs = _gl( n )
                spparams[n] = 0 if vs else 1

                if getattr( spobj, n ) != spparams[n] :
                    extLog.append( u'更改项 [%s] 为 ‘%s’。' % ( label, u'是' if spparams[n] == 0 else u'否' ) )

            spobj.update( spparams )

            oldaset = set( map( lambda v : unicode( v.id ), obj.attachment ) )
            newaset = set( _g( 'attachment', '' ).split( "|" ) )
            deltedAtm = oldaset.difference( newaset )
            if deltedAtm :
                delAtms = qry( SysFile ).filter( SysFile.id.in_( list( deltedAtm ) ) )
                extLog.extend( [u'删除附件[%s]。' % da.name for da in delAtms] )
            obj.attachment = sorted( list( newaset ) ) + multiupload()

            newCopy = obj.serialize()
            makeUpdateLog( obj, oldCopy, newCopy, extLog )
            db.commit()
            flash( MSG_UPDATE_SUCC, MESSAGE_INFO )
        except:
            traceback.print_exc()
            db.rollback()
            flash( MSG_SERVER_ERROR, MESSAGE_ERROR )
            return {'form' : form}
        flash( 'Succ' )
        return redirect( url_for( '.view', action = 'view', id = obj.id ) )


    @allPermission( ['SHOP_DEL', ] )
    def delete( self ):
        sid = _g( 'id' )
        if not sid :
            flash( MSG_NO_ID_SUPPLIED, MESSAGE_ERROR )
            return redirect( url_for( '.view' ) )

        obj = Shop.get( sid )
        if not obj:
            flash( MSG_RECORD_NOT_EXIST, MESSAGE_ERROR )
            return redirect( url_for( '.view' ) )

        try:
            obj.active = 1
            db.add( SysLog( refClz = obj.__class__.__name__, type = LOG_TYPE_DEL, refID = obj.id, ) )
            db.commit()
            flash( MSG_DELETE_SUCC, MESSAGE_INFO )
        except:
            db.rollback()
            flash( MSG_SERVER_ERROR, MESSAGE_ERROR )
        return redirect( url_for( '.view' ) )



    @templated( 'view_log.html' )
    def viewLog( self ):
        sid = _g( 'id' )
        if not sid :
            flash( MSG_NO_ID_SUPPLIED, MESSAGE_ERROR )
            return redirect( url_for( '.view' ) )
        obj = Shop.get( sid )
        if not obj :
            flash( MSG_RECORD_NOT_EXIST, MESSAGE_ERROR )
            return redirect( url_for( '.view' ) )
        return {'obj' : obj}


bpShop.add_url_rule( '/', view_func = ShopView.as_view( 'view' ), defaults = {'action':'index'} )
bpShop.add_url_rule( '/<action>', view_func = ShopView.as_view( 'view' ) )




#===============================================================================
# form class
#===============================================================================

from wtforms import Form, BooleanField, TextField, SelectField, validators
from sys2do.util.wt_helper import MyDateField

class SrhForm( Form ):
    no = TextField( u'店铺编号', )
    name = TextField( u'店铺名称', )
    shopType = SelectField( u'店铺类型', choices = [( '', '' ), ( unicode( SHOP_TYPE_MAIN ), u'主店' ), ( unicode( SHOP_TYPE_BRANCH ), u'分店' )] )
    saleType = SelectField( u'销售方式', choices = [( '', '' ), ( unicode( SHOP_TYPE_MAIN ), u'自营店' ), ( unicode( SHOP_SALE_TYPE_JOIN ), u'加盟店' )] )
    creator = TextField( u'创建人', )
    createTimeFrom = MyDateField( u'创建时间(开始)', )
    createTimeTo = MyDateField( u'创建时间(结束)' )



class AddForm( Form ):
    shortName = TextField( u'店铺简称', )
    name = TextField( u'店铺全称', )
    address = TextField( u'地址', )
    fund = TextField( u'成立资金', )
    legalPerson = TextField( u'法人代表', )
    shopType = SelectField( '店铺类型', choices = [( SHOP_TYPE_MAIN, '总店' ), ( SHOP_TYPE_BRANCH, '分店' )] )
    saleType = SelectField( '销售方式', choices = [( SHOP_SALE_TYPE_SELF, '自营' ), ( SHOP_SALE_TYPE_JOIN, '加盟' )] )

    canSale = BooleanField( u'包含销售产品模块', default = '0' )
    canPurchase = BooleanField( u'包含采购产品模块', default = '0' )
    canGetWarehouse = BooleanField( u'包含仓存模块', default = '0' )
    canUpdateProduct = BooleanField( u'包含更新商品模块', default = '0' )
    canUpdateOfficer = BooleanField( u'包含更新人员模块', default = '0' )
